package com.tangula.web.kashine.business;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.tangula.web.form.DefaultPagingBody;
import com.tangula.web.kashine.entity.AccountEntity;
import com.tangula.web.kashine.entity.ClassEntity;
import com.tangula.web.kashine.entity.EmailForm;
import com.tangula.web.kashine.entity.HistoryEntity;
import com.tangula.web.kashine.entity.HistoryForm;
import com.tangula.web.kashine.entity.LoadOrgStudentForm;
import com.tangula.web.kashine.entity.PagableForm;
import com.tangula.web.kashine.entity.SendForm;
import com.tangula.web.kashine.entity.SendMoneyFoem;
import com.tangula.web.kashine.entity.StudentAccountForm;
import com.tangula.web.kashine.entity.StudentForm;
import com.tangula.web.kashine.entity.StudentOrgRefForm;
import com.tangula.web.kashine.entity.StudentOrganizationRefEntity;
import com.tangula.web.kashine.entity.StudentPageableForm;
import com.tangula.web.kashine.entity.StudentSendMoneyForm;
import com.tangula.web.kashine.repository.AccountEntityRepository;
import com.tangula.web.kashine.repository.ClassEntityRepository;
import com.tangula.web.kashine.repository.ClassStudentRefEntityRepository;
import com.tangula.web.kashine.repository.HistoryEntityRepository;
import com.tangula.web.kashine.repository.OrgStudentRefEntityRepository;
import com.tangula.web.kashine.repository.SendMoneyFoemRepository;
import com.tangula.web.kashine.repository.StudentAccountFormRepository;
import com.tangula.web.kashine.repository.StudentOrganizationRefRepository;

@Service
public class StudentBusinessImpl implements StudentBusiness {
	@Autowired
	AccountEntityRepository accRepo;
	@Autowired
	StudentOrganizationRefRepository stuOrgRefRepo;
	@Autowired
	HistoryEntityRepository historyRepository;
	@Autowired
	ClassStudentRefEntityRepository classStudentRepository;
	@Autowired
	ClassEntityRepository classRepository;
	@Autowired
	SendMoneyFoemRepository sendRepo;
	@Autowired
	StudentAccountFormRepository safRepo;
	@Autowired
	OrgStudentRefEntityRepository osRepo;

	@Override
	public DefaultPagingBody<AccountEntity> loadOrgStudentsOfOrg(LoadOrgStudentForm form) {

		DefaultPagingBody<AccountEntity> res = new DefaultPagingBody<>(form);
		String orgId = form.getOrgId();
		res.setItems(accRepo.findByOrgId(orgId, form.getIndex(),form.getSize()));
		res.setTotal(osRepo.loadOrgStudentCount(orgId));
		return res;
	}

	@Override
	public AccountEntity register(AccountEntity account) {
		if (account != null) {
			if (accRepo.findByEmail(account.getEmail()) == null) {
				account.setBlock("y");
				return accRepo.saveAndFlush(account);
			} else {
				return null;
			}

		} else {
			return null;
		}
	}

	@Override
	public Boolean sendMoneyToTeacher(SendForm send, AccountEntity account) {
		if (send != null) {
			AccountEntity teacher = accRepo.findById(send.getTeacherId()).get();
			StudentOrganizationRefEntity studentOrg = stuOrgRefRepo.findByStudentEmailAndOrgId(account.getId(),
					teacher.getParentOrgOfTeacher());
			try {
				int mon = Integer.parseInt(send.getMoney());

				if (studentOrg.getMoney() >= mon) {
					String classId = classStudentRepository.findByStudentId(account.getId()).get(0).getClassId();
					teacher.setMoney(teacher.getMoney() + mon);
					studentOrg.setMoney(studentOrg.getMoney() - mon);
					HistoryEntity studenthistory = new HistoryEntity();
					studenthistory.setDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					studenthistory.setMoney(mon);
					studenthistory.setUserId(account.getId());
					studenthistory.setHistoryDes("Send Money To" + teacher.getName());
					studenthistory.setChange("-");
					studenthistory.setClassId(classId);
					studenthistory.setResavId(send.getTeacherId());
					historyRepository.saveAndFlush(studenthistory);
					HistoryEntity teacherhistory = new HistoryEntity();
					teacherhistory.setDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					teacherhistory.setMoney(mon);
					teacherhistory.setUserId(send.getTeacherId());
					teacherhistory
							.setHistoryDes("Riceve Money From" + accRepo.findById(account.getId()).get().getName());
					teacherhistory.setChange("+");
					historyRepository.saveAndFlush(teacherhistory);
					if (accRepo.saveAndFlush(teacher) != null && stuOrgRefRepo.saveAndFlush(studentOrg) != null) {
						return true;
					} else {
						return false;
					}

				} else {
					return false;
				}
			} catch (Exception e) {
				return null;
			}
		} else {
			return false;
		}
	}

	@Override
	public DefaultPagingBody<StudentOrgRefForm> showMoney(StudentPageableForm student) {
		if (student != null) {
			List<StudentOrganizationRefEntity> soe = stuOrgRefRepo.findByStudentId(student.getCondition());
			List<StudentOrgRefForm> sof = new ArrayList<StudentOrgRefForm>();

			for (int i = 0; i < soe.size(); i++) {
				StudentOrgRefForm s = new StudentOrgRefForm(soe.get(i).getId(), student.getCondition(),
						soe.get(i).getOrgId(), accRepo.findNameById(soe.get(i).getId()), "");
				sof.add(s);
			}

			DefaultPagingBody<StudentOrgRefForm> d = new DefaultPagingBody<StudentOrgRefForm>(student.getIndex(),
					student.getSize(), sof.size(), sof);
			return d;
		} else {
			return null;
		}
	}

	@Override
	public DefaultPagingBody<HistoryForm> showHistory(StudentPageableForm student) {
		DefaultPagingBody<HistoryForm> d = new DefaultPagingBody<HistoryForm>(student.getIndex(), student.getSize());
		if (student != null) {
			Page<HistoryEntity> page = historyRepository.findByUserId(student.getCondition(), PageRequest
					.of(student.getIndex() - 1, student.getSize(), Sort.by(new Sort.Order(Direction.ASC, "id"))));

			d.setTotal((int) page.getTotalElements());

			d.setItems(page.getContent().stream().map(cur -> {
				HistoryForm h = new HistoryForm();
				h.setId(cur.getId());
				h.setSendTime(cur.getDate());
				h.setSendDesc(cur.getHistoryDes());
				h.setCost(cur.getMoney() + "");
				return h;
			}).collect(Collectors.toList()));

		}
		return d;
	}

	@Override
	public DefaultPagingBody<AccountEntity> loadTeacher(PagableForm form) {
		DefaultPagingBody<AccountEntity> res = new DefaultPagingBody<>(form);
		if (form != null) {
			Page<AccountEntity> cp = accRepo.findByType("STUDENT",
					form.toPageRequest(new Sort.Order(Direction.DESC, "id")));
			res.fill(cp);
		}
		return res;
	}

	@Override
	public AccountEntity seleteStudent(StudentForm student) {
		if (student != null) {
			return accRepo.findById(student.getCondition()).get();
		} else {
			return null;
		}
	}

	@Override
	public AccountEntity blockStudent(StudentForm student) {
		if (student != null) {
			AccountEntity account = accRepo.findById(student.getCondition()).get();
			account.setBlock("n");
			return accRepo.saveAndFlush(account);
		} else {
			return null;
		}
	}

	@Override
	public AccountEntity unblockStudent(StudentForm student) {
		if (student != null) {
			AccountEntity account = accRepo.findById(student.getCondition()).get();
			account.setBlock("y");
			return accRepo.saveAndFlush(account);
		} else {
			return null;
		}
	}

	@Override
	public AccountEntity changePassword(EmailForm student) {
		if (student != null) {
			AccountEntity account = accRepo.findByEmail(student.getEmail());
			account.setPassword(student.getPassword());
			return accRepo.saveAndFlush(account);
		} else {
			return null;
		}
	}

	@Override
	public DefaultPagingBody<ClassEntity> showClass(StudentPageableForm student) {
		if (student != null) {
			List<ClassEntity> lists = classRepository.showClass(student.getCondition(), student.getSize());
			DefaultPagingBody<ClassEntity> dfb = new DefaultPagingBody<>(student.getIndex(), student.getSize(),
					lists.size(), lists);
			return dfb;
		} else {
			return null;
		}
	}

	@Override
	public AccountEntity blockOrUnblockStudent(StudentForm student) {
		if (student != null) {
			return accRepo.findById(student.getCondition()).get();
		} else {
			return null;
		}
	}

	@Override
	public AccountEntity validateExistsAccount(EmailForm emailForm) {
		if (emailForm != null) {
			return accRepo.findByEmail(emailForm.getEmail());
		} else {
			return null;
		}
	}

	@Override
	public DefaultPagingBody<StudentAccountForm> loadAllFreeStudents(PagableForm page) {
		if (page != null) {
			Sort sort = new Sort(Direction.DESC, "id");
			;
			List<AccountEntity> lists = accRepo.findByTypeAndBlock("STUDENT", "y",
					PageRequest.of(page.getIndex() - 1, page.getSize(), sort));

			int count = accRepo.countByTypeAndBlock("STUDENT", "y");

			List<StudentAccountForm> items = new ArrayList<>(lists.size());

			lists.stream()
					.map(in -> new StudentAccountForm(in.getId(), in.getName(), in.getImage(), in.getAccountDesc()))
					.forEach(it -> items.add(it));
			
			DefaultPagingBody<StudentAccountForm> ap = new DefaultPagingBody<StudentAccountForm>(page.getIndex(),
					page.getSize(), count, items );
			return ap;
		} else {
			return null;
		}
	}


	@Override
	public DefaultPagingBody<SendMoneyFoem> loadStudentSendMoneyHistory(StudentSendMoneyForm student) {
		if (student != null) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				String start = sdf.format(student.getStart());
				String end = sdf.format(student.getEnd());
			List<SendMoneyFoem> lists = sendRepo.loadStudentHistory(student.getCondition(),start,end);
			DefaultPagingBody<SendMoneyFoem> d = new DefaultPagingBody<>(student.getIndex(),
					student.getSize(), lists.size(), lists);
			return d;
		} else {
			return null;
		}

	}

	@Override
	public DefaultPagingBody<AccountEntity> loadAllTeachersOfStudent(StudentPageableForm student) {
		if (student != null) {
			List<AccountEntity> lists = accRepo.loadAllTeacherOfStudent(student.getCondition());
			DefaultPagingBody<AccountEntity> dpb = new DefaultPagingBody<>(student.getIndex(), student.getSize(),
					lists.size(), lists);
			return dpb;
		} else {
			return null;
		}
	}

	@Override
	public DefaultPagingBody<AccountEntity> loadAllStudents(PagableForm page) {
		DefaultPagingBody<AccountEntity> ress = new DefaultPagingBody<>(page);
		if (page != null) {
			Page<AccountEntity> accoLists = accRepo.findByType("STUDENT",
					PageRequest.of(page.getIndex() - 1, page.getSize(), new Sort(Direction.DESC, "id")));
			DefaultPagingBody<AccountEntity> res = new DefaultPagingBody<>(page.getIndex(), page.getSize(),
					accoLists.getSize(), accoLists.getContent());
			return res;
		}
		return ress;
	}

	@Override
	public boolean block(String id) {
		AccountEntity stu = accRepo.findById(id).orElse(null);
		if (stu != null) {
			stu.setBlock("n");
			accRepo.saveAndFlush(stu);
		}
		return true;
	}

	@Override
	public boolean unblock(String id) {
		AccountEntity stu = accRepo.findById(id).orElse(null);
		if (stu != null) {
			stu.setBlock("y");
			accRepo.saveAndFlush(stu);
		}
		return true;
	}

	@Override
	public int countByOrgId(String orgId) {
		return stuOrgRefRepo.countByOrgId(orgId);
	}

}
